package main

import (
	"bytes"
	"encoding/gob"
	"fmt"
)

func DeepCopy(dst, src interface{}) error {
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(src); err != nil {
		return err
	}
	return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}

type User struct {
	Name string
}

func main() {
	MapTest()
}

//测试结构体的拷贝
type person struct {
	Name []string
}

var p = person{
	Name: []string{"11", "22"},
}

//结构体是深拷贝，结构体里的切片是浅拷贝
func structCopy() {
	p2 := p
	p2.Name[0] = "33"
	fmt.Println(p, p2) //{[33 22]} {[33 22]}
	p.Name[0] = "44"   //{[44 22]} {[44 22]}
	fmt.Println(p, p2)
}

var m = map[int]string{1: "11"}

//map是浅拷贝，改了一个会改变其他
func MapTest() {
	n := m
	fmt.Println(m, n) //map[1:11] map[1:11]
	m[1] = "22"       //m、n都改变
	m[2] = "33"       //m、n都改变
	fmt.Println(m, n) //map[1:22 2:33] map[1:22 2:33]
}

func gobTest() {
	fmt.Println("引用类型，直接赋值浅拷贝：")
	user1 := &User{
		Name: "why",
	}
	user2 := user1
	m := *user1
	fmt.Println(*user1) //why
	fmt.Println(*user2) //why
	user1.Name = "jzm"
	fmt.Println(*user1) //jzm
	fmt.Println(*user2) //jzm
	fmt.Println(m)
	fmt.Println("\n")

	fmt.Println("值类型，直接赋值深拷贝：")
	user3 := User{
		Name: "why",
	}
	user4 := user3
	fmt.Println(user3) //why
	fmt.Println(user4) //why
	user4.Name = "jzm"
	fmt.Println(user3) //why
	fmt.Println(user4) //jzm
	fmt.Println("\n")

	fmt.Println("引用类型，DeepCopy深拷贝：")
	user5 := &User{
		Name: "why",
	}
	user6 := new(User)
	fmt.Println(*user5)
	fmt.Println(*user6)
	DeepCopy(user6, user5)
	user6.Name = "jzm"
	fmt.Println(*user5)
	fmt.Println(*user6)
	fmt.Println("\n")

	fmt.Println("值类型，DeepCopy深拷贝：")
	user7 := User{
		Name: "why",
	}
	user8 := new(User)
	fmt.Println(user7)
	fmt.Println(*user8)
	DeepCopy(user8, user7)
	user8.Name = "jzm"
	fmt.Println(user7)
	fmt.Println(*user8)
	fmt.Println("\n")
}
